package coreDb

import (
	"context"
	"errors"
	"time"

	"gitee.com/xgh2012/api-core/coreBiz"
	"gitee.com/xgh2012/api-core/coreZapLog"

	"github.com/redis/go-redis/v9"
	"go.uber.org/zap"
)

type RedisConfig struct {
	Addr     string // [host:port]
	Password string
	DB       int

	PoolSize     int
	MinIdleConns int
}

// InitRedis 初始化 Redis 客户端
func InitRedis(cfg RedisConfig) (*redis.Client, error) {
	client := redis.NewClient(&redis.Options{
		Network:  "tcp",
		Addr:     cfg.Addr,
		Password: cfg.Password,
		DB:       cfg.DB,

		// 连接池配置
		PoolSize:     coreBiz.GetDefaultInt(cfg.PoolSize, 15),
		MinIdleConns: coreBiz.GetDefaultInt(cfg.MinIdleConns, 10),

		// 超时设置
		DialTimeout:  5 * time.Second,
		ReadTimeout:  3 * time.Second,
		WriteTimeout: 3 * time.Second,
		PoolTimeout:  4 * time.Second,

		// 重试策略
		MaxRetries:      1,
		MinRetryBackoff: 8 * time.Millisecond,
		MaxRetryBackoff: 512 * time.Millisecond,

		OnConnect: func(ctx context.Context, conn *redis.Conn) error {
			//coreZapLog.Logger.Info("Redis: 成功建立连接", zap.String("addr", addr))
			return nil
		},
	})

	// 检查连接是否成功
	if err := pingRedis(client, cfg.Addr, cfg.DB); err != nil {
		return nil, err
	}

	return client, nil
}

func pingRedis(client *redis.Client, addr string, db int) error {
	ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
	defer cancel()

	if _, err := client.Ping(ctx).Result(); err != nil {
		coreZapLog.Logger.Error("Redis连接失败", zap.Any("addr", addr), zap.Any("coreDb", db), zap.Error(err))
		return err
	}
	return nil
}

// IsRedisRealError 判断错误是否是 真实的错误
func IsRedisRealError(err error) bool {
	if err == nil {
		return false
	}
	if errors.Is(err, redis.Nil) {
		return false
	}
	return true
}

func GetRedisContext() context.Context {
	return context.Background()
}
